package de.fhin.mas.agents.searcher.behaviours;

import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import de.fhin.mas.MASEvents;
import de.fhin.mas.agents.searcher.SearcherAgent;
import de.fhin.mas.util.MessageUtil;

/**
 * Mit dem <tt>IncomingInformHandler</tt> werden alle eingehenden
 * <tt>INFORM</tt>s bearbeitet.
 * 
 * @author Andreas Schmidl
 */
public class IncomingInformHandler extends CyclicBehaviour {

	/** Die eindeutige ID zur Serialisierung ueber das Netzwerk. */
	private static final long serialVersionUID = -827158170670853570L;

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void action() {
		handleTargetObjectReached();
		handleStorageReached();
		handleChargingStationReached();
		handleObjectLoaded();
		handleObjectUnloaded();
		handleObjectLost();

		block();
	}

	/** Behandelt das <tt>target_object_reached</tt> Ereignis. */
	private void handleTargetObjectReached() {
		SearcherAgent searcherAgent = (SearcherAgent) myAgent;
		MessageTemplate targetObjectReachedTpl = MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.TARGET_OBJECT_REACHED.getName(),
						ACLMessage.INFORM, searcherAgent.getNavigator());

		ACLMessage targetObjectReachedMsg = myAgent
				.receive(targetObjectReachedTpl);

		if (targetObjectReachedMsg != null) {
			searcherAgent.cancelEnvironmentScan();
		}
	}

	/** Behandelt das <tt>storage_reached</tt> Ereignis. */
	private void handleStorageReached() {
		SearcherAgent searcherAgent = (SearcherAgent) myAgent;
		MessageTemplate storageReachedTpl = MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.STORAGE_REACHED.getName(), ACLMessage.INFORM,
						searcherAgent.getNavigator());

		ACLMessage storageReachedMsg = myAgent.receive(storageReachedTpl);

		if (storageReachedMsg != null) {
			searcherAgent.cancelEnvironmentScan();
		}
	}

	/** Behandelt das <tt>charging_station_reached</tt> Ereignis. */
	private void handleChargingStationReached() {
		SearcherAgent searcherAgent = (SearcherAgent) myAgent;
		MessageTemplate chargingStationReachedTpl = MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.CHARGING_STATION_REACHED.getName(),
						ACLMessage.INFORM, searcherAgent.getNavigator());

		ACLMessage chargingStationReachedMsg = myAgent
				.receive(chargingStationReachedTpl);

		if (chargingStationReachedMsg != null) {
			searcherAgent.cancelEnvironmentScan();
		}
	}

	/** Behandelt das <tt>object_loaded</tt> Ereignis. */
	private void handleObjectLoaded() {
		SearcherAgent searcherAgent = (SearcherAgent) myAgent;
		MessageTemplate objectLoadedTpl = MessageUtil
				.buildBasicCommunicationTemplate(null, MASEvents.OBJECT_LOADED
						.getName(), ACLMessage.INFORM, searcherAgent
						.getGripper());

		ACLMessage objectLoadedMsg = myAgent.receive(objectLoadedTpl);

		if (objectLoadedMsg != null) {
			/*
			 * TODO awe: Nur falls aufgenommenes Objekt dem gesuchten Zielobjekt
			 * entspricht
			 */
			searcherAgent.pauseTargetSearch();
		}
	}

	/** Behandelt das <tt>object_unloaded Ereignis. */
	private void handleObjectUnloaded() {
		SearcherAgent searcherAgent = (SearcherAgent) myAgent;
		MessageTemplate objectUnloadedTpl = MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.OBJECT_UNLOADED.getName(), ACLMessage.INFORM,
						searcherAgent.getGripper());

		ACLMessage objectUnloadedMsg = myAgent.receive(objectUnloadedTpl);

		if (objectUnloadedMsg != null) {
			/*
			 * TODO awe: Nur falls abgelegtes Objekt dem gesuchten Zielobjekt
			 * entspricht
			 */
			searcherAgent.cancelTargetSearch();
		}
	}

	/** Behandelt das <tt>object_lost</tt> Ereignis. */
	private void handleObjectLost() {
		SearcherAgent searcherAgent = (SearcherAgent) myAgent;
		MessageTemplate objectLostTpl = MessageUtil
				.buildBasicCommunicationTemplate(null, MASEvents.OBJECT_LOST
						.getName(), ACLMessage.INFORM, searcherAgent
						.getGripper());

		ACLMessage objectLostMsg = myAgent.receive(objectLostTpl);

		if (objectLostMsg != null) {
			searcherAgent.resumeTargetSearch();
		}
	}

}
